/*
 * Copyright 2000-2020 YGSoft.Inc All Rights Reserved.
 */
package SystemManagement.Repository;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.mongodb.AggregationOutput;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;


/**
 * 实现Mongodb通用数据操作.
 * @author chenxiangbai <br>
 * @version 1.0.0 2014-1-7 上午11:24:53 <br>
 * @see IMongodbDAO
 * @since JDK 1.6.0
 */

public final class MongodbDAO    {
	
	/**
	 * Mongodb数据操作工具类..
	 */
	@Autowired
	MongoOperations operations;

	
	public <T> T getPO(Class<T> cls, Serializable id) {
		return this.operations.findById(id, cls);
	}

	public <T> T getPO(Class<T> cls, Criteria... queryParam) {
		/**
		 * 如果没有任何条件，返回空
		 */
		if(queryParam==null|| queryParam.length==0)
			return null;
		final Query query = new Query();	 
		for (Criteria criteria : queryParam) {
			if (criteria != null) {
				query.addCriteria(criteria);
			}
		} 
		return this.operations.findOne(query, cls);
	}
	
	public <T> List<T> getPOList(Class<T> cls) {	
		return this.operations.findAll(cls);
	}


	public <T> List<T> getPOListByIds(Class<T> cls, String[] ids) {
		if(ids==null || ids.length==0)
			return new ArrayList<T>();
		final Collection<String> idList = new ArrayList<String>();
		for (String id : ids) {
			idList.add(id);
		}
		return this.operations.find(Query.query(
				Criteria.where(ClassAnnotationUtils.getPrimaryKeyField(cls).getName()).in(idList)), cls);
	}

	public <T> List<T> getPOList(Class<T> cls, Criteria... queryParam) {
		return this.getPOList(cls, null, null, queryParam);
	}

	public <T> List<T> getPOList(Class<T> cls, Paginate paginate, List<Order> orders, Criteria... queryParam) {
		/**
		 * 如果没有任何条件，返回空，如果不作处理，mongdb会查出所有的
		 */
		if(queryParam==null|| queryParam.length==0)
			return new  ArrayList<T>();
		final Query query = new Query();

		if (paginate != null) {
			query.skip(paginate.getPageIndex() * paginate.getPageSize());
			query.limit(paginate.getPageSize());
		} 
		
		if (orders != null && orders.size() > 0) {
			query.with(new Sort(orders));
		}
		for (Criteria criteria : queryParam) {
			if (criteria != null) {
				query.addCriteria(criteria);
			}
		}
		return this.operations.find(query, cls);
	}
//	
//	/**
//	 * 返回数据集的分页对象，包括总记录数和总页数
//	 * 
//	 * @author yaoyasong 2014-12-18
//	 */
//	 
//	public <T> Page<T> getPOPageList(Class<T> cls, Paginate paginate,
//			List<Order> orders, Criteria... queryParam) {
//		
////		if(queryParam==null || queryParam.length==0)
////			return null;
//		final Query query = new Query();
//
//		if (paginate != null) {
//			query.skip(paginate.getPageIndex() * paginate.getPageSize());
//			query.limit(paginate.getPageSize());
//		} 
//		
//		if (orders != null && orders.size() > 0) {
//			query.with(new Sort(orders));
//		}
//		if(queryParam != null) {//查所有
//			for (Criteria criteria : queryParam) {
//				if (criteria != null) {
//					query.addCriteria(criteria);
//				}
//			}
//		}
//		long totalCount = this.getRowCount(cls, queryParam);
//		Page<T> pageResult = new PageImpl<T>(this.operations.find(query, cls),null,totalCount);
//		return pageResult;
//	}


	public <T> long getRowCount(Class<T> cls, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		return this.operations.count(query, cls);
	}

 
 
	public <T> void saveOrUpdatePOList(List<T> boList) {
		for (T po : boList) {
			this.saveOrUpdatePO(po);
		}
	}

	/**
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#saveOrUpdatePO(java.lang.Object) 
	 * @author chenxiangbai 2014-1-7 下午12:36:55 <br>
	 */
	 
	public <T> void saveOrUpdatePO(T po) {
		this.operations.save(po);
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#saveOrUpdateDocument(java.lang.Class, 
	 * java.lang.String, java.lang.Object, org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void saveOrUpdateDocument(Class<T> cls, String propertyName, Object propertyValue,
			Criteria... queryParam) {
		final Map<String, Object> updatePropertys = new HashMap<String, Object>();
		updatePropertys.put(propertyName, propertyValue);
		this.saveOrUpdateDocument(cls, updatePropertys, queryParam);
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#saveOrUpdateDocument(java.lang.Class,
	 *  java.util.Map, org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void saveOrUpdateDocument(Class<T> cls, Map<String, Object> updatePropertys, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		
		Update update = new Update();
		for (Entry<String, Object> updateProperty : updatePropertys.entrySet()) {  
			update.set(updateProperty.getKey(), updateProperty.getValue());
		  }  
		 
		this.operations.updateMulti(query, update, cls);
	}
	
	 
	public <T> void UpdateUnsetDocument(Class<T> cls, List<String> unsetPropertys, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		
		Update update = new Update();
		for (String updateProperty : unsetPropertys) {  
			update.unset(updateProperty);
		  }   
		this.operations.updateMulti(query, update, cls);
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deleteDocument(java.lang.Class, java.lang.String, 
	 * org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void deleteDocument(Class<T> cls, String propertyName, Criteria... queryParam) {
		final String[] propertyNames = new String[] { propertyName };
		this.deleteDocument(cls, propertyNames, queryParam);
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deleteDocument(java.lang.Class, java.lang.String[], 
	 * org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void deleteDocument(Class<T> cls, String[] propertyNames, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		
		Update update = new Update();
		for (String propertyName : propertyNames) {
			update.set(propertyName, null);
		}

		this.operations.updateMulti(query, update, cls);
		
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#saveArray(java.lang.Class, java.lang.String, 
	 * java.lang.Object, org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void saveArray(Class<T> cls, String propertyName, Object value, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		Update update = new Update(); 
		update.push(propertyName, value);
		this.operations.upsert(query, update, cls);
		 
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deleteArray(java.lang.Class,
	 *  java.lang.String, java.lang.Object, org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void deleteArray(Class<T> cls, String propertyName, Object value, Criteria... queryParam) {
	 	
		 final Query query = createQuery(queryParam);
		Update update = new Update(); 
		update.pull(propertyName, value);
		this.operations.updateMulti(query, update, cls);		
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deleteArray(java.lang.Class,
	 *  java.lang.String, java.lang.Object[], org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void deleteArray(Class<T> cls, String propertyName, Object[] values, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		Update update = new Update(); 		 
		update.pullAll(propertyName, values);
		this.operations.upsert(query, update, cls);		 
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#saveOrUpdateObjectArray(java.lang.Class,
	 *  java.lang.String, java.lang.Object, org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void saveOrUpdateObjectArray(Class<T> cls, String propertyName, Object value, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		Update update = new Update(); 
		update.set(propertyName, value);
		this.operations.upsert(query, update, cls);
		
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deleteObjectArray(java.lang.Class, java.lang.String, 
	 * org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void deleteObjectArray(Class<T> cls, String propertyName, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		Update update = new Update(); 
		update.unset(propertyName);
		this.operations.upsert(query, update, cls);		
		
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#updateInc(java.lang.Class, java.lang.String, 
	 * org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-2-17 下午2:47:59 <br> 
	 */
	 
	public <T> void updateInc(Class<T> cls, String propertyName,int inc, Criteria... queryParam) {
		final Query query = createQuery(queryParam);
		Update update = new Update(); 
		update.inc(propertyName, inc); 
		this.operations.updateMulti(query, update, cls);		
	}

	/**
	 * 根据动态查询参数创建Query. <br>
	 * @author chenxiangbai 2014-1-7 下午5:51:44 <br> 
	 * @param queryParam 动态查询参数
	 * @return Query. 
	 */
	private Query createQuery(Criteria... queryParam) {
		final Query query = new Query();
		if(queryParam != null) {
			for (Criteria criteria : queryParam) {
				if (criteria != null) {
					// qiushaohua@2014-03-06 增加判断
					query.addCriteria(criteria);
				}
			}
		}
		return query;
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deletePO(java.lang.Object) 
	 * @author chenxiangbai 2014-1-7 下午12:36:58 <br>
	 */
	 
	public <T> void deletePO(T po) {
		this.operations.remove(po);
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deletePO(java.lang.Class, java.io.Serializable) 
	 * @author chenxiangbai 2014-1-7 下午12:37:01 <br>
	 */
	 
	public <T> void deletePO(Class<T> cls, Serializable id) {
		this.operations.remove(new Query(Criteria.where(ClassAnnotationUtils.getPrimaryKeyField(cls).getName()).is(id)), cls);		
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deletePOList(java.lang.Class, java.util.List) 
	 * @author chenxiangbai 2014-1-7 下午12:37:03 <br>
	 */
	 
	public <T> void deletePOList(Class<T> cls, List<T> poList) {
		for (T po : poList) {
			this.deletePO(po);
		}
	}

	/** 
	 * {@inheritDoc}
	 * @see com.ygsoft.community.IMongodbDAO.service.mongodb.IMongodbDAO#deletePOList(java.lang.Class,
	 *  org.springframework.data.mongodb.core.query.Criteria[]) 
	 * @author chenxiangbai 2014-1-7 下午4:45:12 <br> 
	 */
	 
	public <T> void deletePOList(Class<T> cls, Criteria... queryParam) {
		final Query query = createQuery(queryParam);		
		this.operations.remove(query, cls);		
	}
	/**
	 * 
	 */
	 
	@SuppressWarnings("unchecked")
	public <T> List<T> getPoDistinct(String collectionName,String key,final Criteria... queryParam) {
		/**
		 * 如果没有任何条件，返回空，如果不作处理，mongdb会查出所有的
		 */
		if(queryParam==null|| queryParam.length==0)
			return new  ArrayList<T>();
		Query query = createQuery(queryParam); 	 
		return  this.operations.getCollection(collectionName).distinct(key, query.getQueryObject());
	}
	
	 
	@SuppressWarnings("unchecked")
	public <T> List<T> getPODistinctList(String collectionName,String key, Paginate paginate, List<Order> orders, final Criteria... queryParam){
		/**
		 * 如果没有任何条件，返回空，如果不作处理，mongdb会查出所有的
		 */
		if(queryParam==null|| queryParam.length==0)
			return new  ArrayList<T>();
		final Query query = new Query();

		if (paginate != null) {
			query.skip(paginate.getPageIndex() * paginate.getPageSize());
			query.limit(paginate.getPageSize());
		} 
		
		if (orders != null && orders.size() > 0) {
			query.with(new Sort(orders));
		}
		for (Criteria criteria : queryParam) {
			if (criteria != null) {
				query.addCriteria(criteria);
			}
		} 
		
		return  this.operations.getCollection(collectionName).distinct(key, query.getQueryObject());
	}
	 
	@SuppressWarnings("unused")
    public void get(String collectionName,String key,String value){
		/* 创建 $unwind 操作, 用于切分数组*/ 
		DBObject match = new BasicDBObject("$match", new BasicDBObject(key, value));  
		 DBObject group = new BasicDBObject("$group", new BasicDBObject("userSelects.selectNum", -1));
		 @SuppressWarnings("deprecation")
		AggregationOutput output = this.operations.getCollection(collectionName).aggregate(match, group); 
	}

//	/**
//	 * {@inheritDoc}
//	 * @see com.ygsoft.community.persistence.mongodb.IMongodbDAO#unionList(java.util.List, int, java.util.List[])
//	 */
//	 
//	public <T> List<T> unionList(final List<Order> orderList, final int count, final List<T>... list) {
//        final List<T> sortList = new ArrayList<T>();       
//        for (List<T> listTemp : list) {
//        	sortList.addAll(listTemp);
//		}
//  
//        // 在合并的集合的数量大于1个时才排序
//        if (sortList.size() > 1) {
//	        // 声明要排序的对象的属性，并指明所使用的排序规则，如果不指明，则用默认排序   
//	        final ArrayList<Object> sortFields = new ArrayList<Object>();     
//	        if(CollectionUtils.isNotEmpty(orderList)){
//	        	for (Order order : orderList) {
//		        	// 创建一个排序规则   
//		            Comparator comparator = ComparableComparator.getInstance();       
//		            comparator = ComparatorUtils.nullLowComparator(comparator);  
//		            if (!order.isAscending()) {
//		            	comparator = ComparatorUtils.reversedComparator(comparator);
//		            } 
//		            sortFields.add(new BeanComparator(order.getProperty(), comparator));
//				}
//	        	
//	        	 // 创建一个排序链   
//		        final ComparatorChain multiSort = new ComparatorChain(sortFields);    
//		        // 开始真正的排序
//		        Collections.sort(sortList, multiSort); 
//	        }
//	        
//	        if (sortList.size() > count && count>0) {
//	        	return sortList.subList(0, count);
//	        } else {
//	        	return sortList;
//	        }
//        } else {
//        	return sortList;
//        }
//	}

	 
	public <T> List<BasicDBObject> groupBy(Class<T> cls,String[] propertyName, Criteria... queryParam) {
		Criteria criteria =null;
		if(queryParam != null){
			criteria = new Criteria();
				criteria.andOperator(queryParam);
		}
		 GroupBy groupBy = GroupBy.key(propertyName).initialDocument("{count:0}").reduceFunction("function(doc, prev){prev.count+=1}");
		 GroupByResults<T> resluts = operations.group(criteria,operations.getCollectionName(cls), groupBy,cls);
		 if(resluts != null){
			 @SuppressWarnings("unchecked")
			List<BasicDBObject> list = (List<BasicDBObject>) resluts.getRawResults().get("retval");	
			 return list;
		 }
		  return null;
	}

	 
	public List<Order> orderDescBy(String... properNames) {
		if(properNames !=null && properNames.length > 0){
			int len = properNames.length;
			List<Order> orders = new ArrayList<Order>();
			for(int i=0;i<len;i++ ){
				Order order = new Order(Direction.DESC,properNames[i]);
				orders.add(order);
			}
			return orders;
		}
		return null;
	}

	 
	public <T> Long sum(Class<T> cls, String propertyName,Criteria... queryParam) {
	   Long total = 0L;	   
	   Criteria criteria =null;
		if(queryParam != null){
			criteria = new Criteria();
				criteria.andOperator(queryParam);
		}
		Query query = Query.query(criteria);
		String reduce = "function (doc,aggr) { aggr.total += doc."+propertyName+"}";
	    DBObject results = operations.getCollection(
	    				operations.getCollectionName(cls)).group(new BasicDBObject(propertyName, 1), 
	    				query.getQueryObject(), new BasicDBObject("total", total), reduce);	
		return Long.parseLong((String) results.get("total"));
	}

	 
	public <T> List<BasicDBObject> sumArray(Class<T> cls, String propertyName,String showName,
			Criteria... queryParam) {
		Long total = 0L;	   
		   Criteria criteria =null;
			if(queryParam != null){
				criteria = new Criteria();
					criteria.andOperator(queryParam);
			}
			Query query = Query.query(criteria);
			String reduce = "function (doc,aggr) {"
					+ "for (var i in doc."+propertyName+"){"
							+ "aggr.total +=1}}";
		    DBObject results = operations.getCollection(
		    				operations.getCollectionName(cls)).group(new BasicDBObject(showName, 1), 
		    				query.getQueryObject(), new BasicDBObject("total", total), reduce);
		    @SuppressWarnings("unchecked")
			Map<String,BasicDBObject> map =  results.toMap();
		    List<BasicDBObject> list = new ArrayList<BasicDBObject>();
		    for (String key : map.keySet()) {
		    	list.add(map.get(key));
		    }		
		return list;
	}

	 
	public List<Order> orderAscBy(String... properNames) {
		if(properNames !=null && properNames.length > 0){
			int len = properNames.length;
			List<Order> orders = new ArrayList<Order>();
			for(int i=0;i<len;i++ ){
				Order order = new Order(Direction.ASC,properNames[i]);
				orders.add(order);
			}
			return orders;
		}
		return null;
	}

	 
//	public <T> Long sum(Class<T> cls, String propertyName, String groupName,
//			Criteria... queryParam) {
//		Long total = 0L;	   
//		   Criteria criteria =null;
//			if(queryParam != null){
//				criteria = new Criteria();
//					criteria.andOperator(queryParam);
//			}
//			Query query = Query.query(criteria);
//			String reduce = "function (doc,aggr) { aggr.total += doc."+propertyName+"}";
//		    List<DBObject> results = (List<DBObject>) operations.getCollection(
//		    				operations.getCollectionName(cls)).group(new BasicDBObject(groupName, 1), 
//		    				query.getQueryObject(), new BasicDBObject("total", total), reduce);
//		    
//		    if(CollectionUtils.isNotEmpty(results)){
//		    	DBObject result = results.get(0);
//				return new Double(result.get("total")+"").longValue();
//		    }
//	     return 0L;
//	}

	 
//	public <T> Double sumDouble(Class<T> cls, String propertyName,
//			String groupName, Criteria... queryParam) {
//		 Criteria criteria =null;
//		 Double total = 0.00;
//			if(queryParam != null){
//				criteria = new Criteria();
//					criteria.andOperator(queryParam);
//			}
//			Query query = Query.query(criteria);
//			String reduce = "function (doc,aggr) { aggr.total += doc."+propertyName+"}";
//		    List<DBObject> results = (List<DBObject>) operations.getCollection(
//		    				operations.getCollectionName(cls)).group(new BasicDBObject(groupName, 1), 
//		    				query.getQueryObject(), new BasicDBObject("total", total), reduce);
//		    
//		    if(CollectionUtils.isNotEmpty(results)){
//		    	DBObject result = results.get(0);
//				return new Double(result.get("total")+"");
//		    }
//		return total;
//	}

	 
	public <T> List<T> getPoList(Class<T> cls,
								 Map<String, Integer> resultProperty, Criteria... queryParam) {

		if(resultProperty != null){
			BasicDBObject fieldsObject=new BasicDBObject();

			for(String keySet : resultProperty.keySet()) {
				fieldsObject.put(keySet, resultProperty.get(keySet));
			}

			Query query = new BasicQuery(new BasicDBObject(),fieldsObject);

			for (Criteria criteria : queryParam) {
				if (criteria != null) {
					query.addCriteria(criteria);
				}
			}
			return	this.operations.find(query, cls);
		}
		return null;
	}

	 
	public <T> List<BasicDBObject> groupByMax(Class<T> cls,String[] propertyName, Criteria... queryParam) {
		Criteria criteria = null;
		if (queryParam != null) {
			criteria = new Criteria();
			criteria.andOperator(queryParam);
		}
		GroupBy groupBy = GroupBy.key(propertyName).initialDocument("{score:0.0}")
				.reduceFunction("function(doc, prev){prev.score=(doc.score>prev.score?doc.score:prev.score)}");
		GroupByResults<T> resluts = operations.group(criteria, operations.getCollectionName(cls), groupBy, cls);
		if (resluts != null) {
			@SuppressWarnings("unchecked")
			List<BasicDBObject> list = (List<BasicDBObject>) resluts.getRawResults().get("retval");
			return list;
		}
		return null;
	}
 
	/**
	 * 聚合分组分页查询
	 * linyuebin 2017-11-22
	 * @param cls
	 * @param match 条件
	 * @param group 分组
	 * @param sort 排序
	 * @param pageNo 分页
	 * @param pageSize 分页
	 * @return
	 */
	 
	public <T> Iterable<DBObject> aggregate(Class<T> cls,DBObject match,DBObject group,DBObject sort,int pageNo, int pageSize){

		if(pageNo!=0&&pageSize!=0){
			DBObject skip=new BasicDBObject("$skip",pageSize*(pageNo-1));
			DBObject limit=new BasicDBObject("$limit",pageSize);

			@SuppressWarnings("deprecation")
			AggregationOutput output =operations.getCollection(operations.getCollectionName(cls)).aggregate(match,group,sort,skip,limit);
		
	 
			return  output.results();  
		}else{
			@SuppressWarnings("deprecation")
			AggregationOutput output =operations.getCollection(operations.getCollectionName(cls)).aggregate(match,group,sort);
			return  output.results();  
		}

		
	}

}
